import datetime
import sys
from typing import List, Dict

from sqlalchemy import Boolean, Column, DateTime, String, Index, text, TEXT, distinct, or_
from sqlalchemy.orm import Session, relationship

from core.logger import logger
from common.database import Base
from common.database import SessionMixin
from app.auth.models.auth_roles_permissions import AuthRolesPermissions

__all__ = ['AuthPermissions']


class AuthPermissions(Base, SessionMixin):
    """
    基于角色权限控制-权限表
    """
    __tablename__ = "auth_permissions"
    permission_name = Column(String(255), nullable=False, comment='权限名称')
    method = Column(String(8), nullable=True, comment='路由方式')
    url = Column(String(255), nullable=True, comment='路由地址')
    tags = Column(String(255), nullable=True, comment='路由标签')
    summary = Column(String(255), nullable=True, comment='概要说明')
    description = Column(String(255), nullable=True, comment='权限描述')
    auth_roles = relationship('AuthRoles', secondary=AuthRolesPermissions, back_populates='auth_permissions',
                              lazy='dynamic')
    create_time = Column(DateTime, default=datetime.datetime.now, nullable=False, comment="创建时间")
    update_time = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, nullable=False,
                         comment="更新时间")

    __table_args__ = (
        Index('idx_auth_permissions_uuid', 'uuid', unique=True),
        Index('idx_auth_permissions_name', 'permission_name', unique=True),
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic',
        }
    )

    def __repr__(self):
        return "<uuid='{}',permission_name='{}'>".format(self.uuid, self.permission_name)

    @classmethod
    def get_by_uuid(cls, db: Session, uuid: str) -> Dict:
        return db.query(cls).filter(cls.uuid == uuid).to_dict()

    @classmethod
    def get_by_permission_name(cls, db: Session, permission_name: str) -> Dict:
        return db.query(cls).filter(cls.permission_name == permission_name).to_dict_first()


    @classmethod
    def get_paginate(cls, db: Session, page: int, per_page: int, field: str, value: str) -> List[Dict]:
        try:
            search_field = []
            if value:
                for key, col in cls.__table__.c.items():
                    if field == "all" or key == field: search_field.append(col.like(f"%{value}%"))
            result = db.query(cls).filter(or_(*search_field)). \
                with_entities(cls.uuid, cls.tags, cls.method, cls.url, cls.summary, cls.description).paginate(
                page=page, per_page=per_page)
        except Exception as e:
            logger.error(f'{sys._getframe().f_code.co_name} {e}')
            return []

        result["fields"] = cls.get_display_field_meta()
        return result
